<?php
// +----------------------------------------------------------------------
// | INPHP
// +----------------------------------------------------------------------
// | Copyright (c) 2021 https://inphp.cc All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://opensource.org/licenses/MIT )
// +----------------------------------------------------------------------
// | Author: lulanyin <me@lanyin.lu>
// +----------------------------------------------------------------------
namespace Inphp\Attributes;

use ReflectionClass;
use ReflectionException;

class Attributes
{
    /**
     * 初始化注解
     */
    public static function init()
    {

    }

    /**
     * 注解处理
     * @param $controller
     * @param string|null $method
     * @throws ReflectionException
     */
    public static function process($controller, string|null $method = null)
    {
        if(!is_object($controller))
        {
            return;
        }
        //获
        try
        {
            //类
            $ref = new ReflectionClass($controller::class);
            $attrs = $ref->getAttributes();
            self::execute('class', $attrs, $controller);
            //类属性注解
            $properties = $ref->getProperties();
            foreach ($properties as $property)
            {
                $p_attrs = $property->getAttributes();
                self::execute('property', $p_attrs, $controller, $property->getName());
            }
            //方法注解
            if(!empty($method))
            {
                $m_ref = $ref->getMethod($method);
                $m_attrs = $m_ref->getAttributes();
                self::execute('method', $m_attrs, $controller, $method);
            }
        }
        catch (ReflectionException $exception)
        {
            //
            throw new ReflectionException("注解处理失败：".$exception->getMessage()."，{$exception->getFile()}第{$exception->getLine()}行", $exception->getCode());
        }
    }

    /**
     * 统一执行注解处理
     * @param $type
     * @param $attrs
     * @param $controller
     * @param null $target
     */
    private static function execute($type, $attrs, $controller, $target = null)
    {
        foreach ($attrs as $attr)
        {
            $instance = $attr->getName();
            $args = $attr->getArguments();
            $args = !empty($args) ? $args[0] : [];
            $init = new $instance($args);
            if(method_exists($init, 'process'))
            {
                $init->process($type, $controller, $target);
            }
        }
    }
}